home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-01-11 | 7.5 KB | 268 lines | [TEXT/KAHL] |
- // File "event filter.c" -
- // This source file is Copyright Matt Slot & Slot-Machines Ltd., © 1994
-
- #include <GestaltEqu.h>
- #include "TextServices.h"
-
- #include "main.h"
- #include "contexts.h"
- #include "event filter.h"
- #include "windows.h"
-
- // * ****************************************************************************** *
- // Global Vars
-
- extern GlobalsRec glob;
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- void InsertMyFilter() {
- Ptr filterPtr, endFilterPtr, helpFilterPtr;
-
- // Load up the Filter Handler
- asm {
- lea MyJGNEFilter, a0
- move.l 2(a0), filterPtr
- lea EndJGNEFilter, a0
- move.l 2(a0), endFilterPtr
- lea HelperJGNEFilter, a0
- move.l 2(a0), helpFilterPtr
- }
- glob.myContext = SaveContext(-1);
-
- // Duplicate function in safe spot - System Heap
- glob.myFilter = NewPtrSys(StripAddress(endFilterPtr) - StripAddress(filterPtr));
- BlockMove(filterPtr, glob.myFilter, GetPtrSize(glob.myFilter));
-
- // Get Appropriate Info and stuff into Header of JGNEFilter
- BlockMove((Ptr) 0x29a, glob.myFilter+2, 4); // Next Filter
- BlockMove(&glob.myContext, glob.myFilter+6, 4); // Context Info
- BlockMove(&helpFilterPtr, glob.myFilter+10, 4); // Address of Local Handler
-
- BlockMove(&glob.myFilter, (Ptr) 0x29a, 4); // Save into Lo-Mem Global
- }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- void RemoveMyFilter() {
- Ptr loadPtr;
-
- // Actually, just disable the filter by stuffing 0 into the Event Handler storage
-
- DisposeContext(glob.myContext);
-
- loadPtr = glob.myFilter;
- asm {
- move.l loadPtr, a0
- move.l #0, 10(a0)
- }
- }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- void DisableMyFilter(short enable) {
- Ptr loadPtr, helpFilterPtr;
-
- loadPtr = glob.myFilter;
-
- if (enable) {
- asm {
- lea HelperJGNEFilter, a0
- move.l 2(a0), helpFilterPtr
- move.l loadPtr, a0
- move.l helpFilterPtr, 10(a0)
- }
- }
- else {
- asm {
- move.l loadPtr, a0
- move.l #0, 10(a0)
- }
- }
- }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- void MyJGNEFilter() {
- asm {
- bra.s @Continue
-
- @Next_Filter
- dc.l 0 ; Saved Address of Next jGNEFilter
-
- @Saved_Context
- dc.l 0 ; Saved Context Info for our App
-
- @Event_Helper
- dc.l 0 ; The function in my app to call
-
- @Continue
- movem.l d0-d2/a0-a5, -(a7)
- move.l @Event_Helper, a0
- move.l a0, d0
- tst.l d0
- beq @End_Filter
-
- move.l @Saved_Context, a0
- move.l a0, -(a7)
- move.l a1, -(a7)
- move.l @Event_Helper, a0
- jsr (a0)
- add.l #8, a7
-
- @End_Filter
- movem.l (a7)+, d0-d2/a0-a5
- move.l @Next_Filter, a0
- jmp (a0)
- }
- }
- void EndJGNEFilter() { }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- void HelperJGNEFilter(EventRecord *theEvent, ContextPtr myContext) {
- short thePart, cloneFile;
- Rect dragBounds;
- ContextPtr frontContext;
- WindowPtr theWindow, frontWindow;
-
- frontContext = SaveContext(0);
- RestoreContext(myContext); // DONT USE GLOBAL CONTEXT YET - A5 isnt set up
- glob.frontContext = frontContext; // Put the Apps context info into the Globals
- UseResFile(cloneFile = FSpOpenResFile(&glob.cloneSpec, fsRdPerm));
-
- glob.theEvent = *theEvent;
-
- // We need to manually look for an update event -- otherwise it wont happen
- if (!EmptyRgn(((WindowPeek) glob.window)->updateRgn)) DoUpdateWindow();
-
- switch(theEvent->what) {
- case nullEvent:
- DoCheckVisibility();
- break;
-
- case mouseDown:
- // The following line shouldnt be necessary... but PopupFuncs
- // doesnt like the FindServiceWindow() call... so we try to avoid it.
- // Just eliminate a few checks in some cases that we know are wrong.
- if (!PtInRgn(theEvent->where, ((WindowPeek) glob.window)->strucRgn)) break;
-
- thePart = FindServiceWindow(theEvent->where, &theWindow);
- if (theWindow != glob.window) break;
- GetFrontServiceWindow(&frontWindow);
-
- switch(thePart) {
- case inContent:
- if (theWindow != frontWindow) {
- SelectWindow(theWindow);
- DoUpdateWindow();
- }
- DoClickWindow();
- theEvent->what = nullEvent;
- break;
- case inDrag:
- // Generic Dragger Handling
- if (theWindow != frontWindow) {
- SelectWindow(theWindow);
- DoUpdateWindow();
- }
- dragBounds = (*GetGrayRgn())->rgnBBox;
- DragWindow(theWindow, theEvent->where, &dragBounds);
- theEvent->what = nullEvent;
- break;
- case inGrow:
- // I dont think anyone will grow a floater, so just ...
- DoClickWindow();
- theEvent->what = nullEvent;
- break;
- case inGoAway:
- // Exit gracefully - Finish this Event first
- if (TrackGoAway(theWindow, theEvent->where)) glob.quitting = 1;
- theEvent->what = nullEvent;
- break;
- case inZoomIn:
- case inZoomOut:
- if (TrackBox(theWindow, theEvent->where, thePart))
- DoZoomWindow(thePart);
- theEvent->what = nullEvent;
- break;
- default:
- break;
- }
- break;
-
- case autoKey:
- case keyDown:
- if (DoKeydownWindow()) theEvent->what = nullEvent;
- break;
-
- default:
- break;
- }
-
- CloseResFile(cloneFile);
- RestoreContext(frontContext);
- DisposeContext(frontContext);
- }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- // If you have set the Hot Application, then this function checks whether that
- // process is the front one and hides or shows the window as appropriate.
- void DoCheckVisibility() {
- ProcessSerialNumber psn;
- ProcessInfoRec pInfo;
-
- pInfo.processInfoLength = sizeof(pInfo);
- pInfo.processName = 0;
- pInfo.processAppSpec = 0;
-
- if (!GetFrontProcess(&psn) && !GetProcessInformation(&psn, &pInfo)) {
- if (!glob.hidden && (!InScreenSaver()) &&
- ((glob.hotApplication == kAllApplications) ||
- (pInfo.processSignature == glob.hotApplication))) {
- if (! ((WindowPeek) glob.window)->visible) {
- ShowHide(glob.window, -1);
- DoRevealWindow(-1);
- }
- }
- else if (((WindowPeek) glob.window)->visible) {
- ShowHide(glob.window, 0);
- DoRevealWindow(0);
- }
- }
- }
-
- // * ****************************************************************************** *
- // * ****************************************************************************** *
-
- // Thanks to Dair Grant (dair.grant@ucl.ac.uk) - I now check the MBarHeight
- // of the *Front* process, and remember (via globals) when executing in bkgd.
-
- short InScreenSaver() {
- short err, inFront;
- long result;
- ProcessSerialNumber frontPSN, curPSN;
-
- // Most screensavers should register themselves this way
- if (!Gestalt('SAVR', &result) && (result & 0x02)) return(-1);
-
- // We also want to hide ourselves if the foreground application
- // has hidden the menu bar, since this implies they're taking
- // over the whole screen (and they probably don't want us visible).
-
- // If we are executing in the foreground app, then cache the
- // height of the menu bar for when we swap to the background.
- if (!GetFrontProcess(&frontPSN) && !GetCurrentProcess(&curPSN))
- if (SameProcess(&frontPSN, &curPSN, (Boolean *) &inFront)) inFront = 0;
- if (inFront) glob.frontMBarHeight = GetMBarHeight();
-
- return(! glob.frontMBarHeight);
- }
-